/**
*  \file   li_ion_pred_bat.c
*
*  \brief  Power-Reduction depending on li-ion's battery current-prediction
*          Control functions
*
*  \author Thomas Wenzel <thomas.wenzel@linde-mh.de>
*
*/

/*===============================================[ private includes  ]================================================*/
#include "li_ion_pred_bat.h"
#include "li_ion.h"
#include "li_ion_term.h"
//#include "../cfg/lithium_ion_cfg.h"                                                            /* Configuration       */
//#include "../distmem/distmem.h" /* UC2, .. */
#include "../mlib/middle.h"     /* middle_f32(), .. */
#include "../input/input.h"

/*===============================================[ private defines   ]================================================*/

/*===============================================[ private datatypes ]================================================*/

/*===============================================[ private variables ]================================================*/
static F32 f32MaxCurrentRegenF;

/*===============================================[ public variables  ]================================================*/
BO li_bPowerReduction_iBat;

/*===============================================[ private functions ]================================================*/

/**
*  charge_current_filt_2ms:
*  \return  filtered input
*/
__inline static void charge_current_filt_2ms(F32 Te, F32 *Tef, F32 tau)
{
   if (in_Time() < 2.0f)
   {
      *Tef = Te;                          /* no filter at begin                  */
   }
   else
   {
      *Tef += (Te - *Tef) * (0.002F / tau);   /* 1st order low pass filter otherwise */
   }
}

/*====================================================================================================================*/

/**
*  Initialization.
*
*  Initialize the power-reduction module.
*
*  \return RC_SUCCESS if successful.
*/
RC li_ion_pred_ibat_initialize ( VO )
{
   li_bPowerReduction_iBat = FALSE;        /* Signal to supervisor */
   li_PowerReductionPerc   = 100;          /* 100%: Volle Leistung */

   return RC_SUCCESS;
}

/*====================================================================================================================*/

/**
*  f32iCurLimitTorqueSet_2ms:
*  On trucks with lithium-ion-battery power-reduction related to pre-dicted ChargeCurrent-Value

      f32iCurLimitTorqueSet_2ms: Limit brake torque at low Lithium-Ion's Battery Current


             |
       mSet _|         ____________________
             |        /
             |       /
           y1|      /
             |     /
             |    /
             |   /
           y2|  /
             | /
             |/
              ��������:��������������������������
             0A/low   450A/high
*
*           function call :   lim = delta(torqueset, actspeed);
*  \param   f32TorqueSet F32 variable
*  \param   f32ActSpeed  F32 variable
*  \return  Limited torque-setpoint
*/
F32 f32iCurLimitTorqueSet_2ms(F32 f32TorqueSet,
                              F32 f32ActSpeed)
{
   F32 f32MaxCurrentRegen;
   F32 f32Factor;
   F32 q1_q0;
   F32 f32RetValue;

   /* ==================================== */
   /* Initialize in any case return-value: */
   /* ==================================== */
   f32RetValue = f32TorqueSet;

   /* ================================================================== */
   /* Evaluate percentage-offset to start of power-reduction: 0.0 .. 1.0 */
   /* ================================================================== */
   f32MaxCurrentRegen = sLiIon.CAN_LiIoBMS_MaxChargeCurrent_2sec_A;                           /* Predicted BMS-Charge-Current: [A] */

   /* ========================================================= */
   /* Process 500ms-PT1-Filter because of 100ms-CAN-cycle-time: */
   /* ========================================================= */
   charge_current_filt_2ms(f32MaxCurrentRegen, &f32MaxCurrentRegenF, 0.500F);

   if (f32MaxCurrentRegenF < (F32)li_LiIoniBatHigh)
   {
      q1_q0     = middle_f32(0.001f, (F32)(li_LiIoniBatHigh - li_LiIoniBatLow), 1500.0f);     /* Limited to 1500[A] */
      f32Factor = middle_f32(0.45f, (f32MaxCurrentRegenF - li_LiIoniBatLow) / q1_q0, 1.0f);   /* 0.45 .. 1.0         */
   }
   else
   {
      f32Factor = 1.0F;
   }

   li_PowerReductionPerc = (S16)(100.0F * f32Factor);            /* For diagnosis: 100%: Volle Leistung                                          */

   if (    ((f32TorqueSet > 0.0F) && (f32ActSpeed < 0.0F))
        || ((f32TorqueSet < 0.0F) && (f32ActSpeed > 0.0F)) )     /* Detect regen-mode: */
   {
      if (f32MaxCurrentRegenF < (F32)li_LiIoniBatHigh)
      {
         f32RetValue             = f32Factor * f32TorqueSet;     /* Limitation is done here */
         li_bPowerReduction_iBat = TRUE;                         /* Signal to supervisor    */
      }
      else
      {
         li_bPowerReduction_iBat = FALSE;                        /* Signal to supervisor    */
      }
   }
   else
   {
      li_bPowerReduction_iBat = FALSE;                           /* Signal to supervisor    */
   }

   return ( f32RetValue ) ;

}

/***********************************************************************************************************************
*                             Copyright 2013 Linde Material Handling. All rights reserved.                             *
***********************************************************************************************************************/
